﻿using System;
using System.Threading;
using System.Windows.Forms;
using System.Globalization;
using ALDIOrganizer.Properties;

namespace ALDIOrganizer
{
    public partial class Program
    {
        public static Logon frmLogon;        
        public static MainForm frmMain;
        public static EditNotes frmEditNotes;
        public static AddRowToTemplate addempForm;
        public static WorkingHours workinghrsForm;
        public static SetGeneratorParameters generaterotaForm;
        public static GeneratingRota generatorForm;        
        
        public static Loading LoadingForm;
        public static formAboutProgram aboutForm;
        public static GeneratorReport reportForm;

        public static ChooseWeek ChooseWeekForm;
        public static ImportTemplates formImportTemplates;
        
        #region data input forms
        public static RequestDetails requestForm;        
        public static AddNewEmployee addempToStaffForm;
        public static ForWhom ChooseEmployee;
        public static HolidayDetails holidayForm;
        public static ContractDetails contractForm;
        public static UpdateEmployee updateEmployeeForm;
        public static ContractNewOrUpdate newOrUpdateForm;
        public static SetDayStatus specialStatusForm;
        public static formInputTemplateName inputTemplateNameForm;
        public static TemplateModificationReaction reactToTemplateModificationForm;
        public static ChooseTemplate frmChooseBaseTemplate;
        public static OpenFiles OpenFilesForm;
        #endregion

        
        public static Theme CurrentTheme;
        
        /// <summary>
        /// Most recently used SQLite CurrentFile files
        /// </summary>
        internal static MRUTracker MRUSQLFiles;
        /// <summary>
        /// Most recently used rotas/templates filse
        /// </summary>
        internal static MRUTracker MRURotasFiles;
        /* Here we remember (and refer to later On), which language user has chosen - Polish or English.
         * Why not assign this CurrentCulture to the current thread?
         * And why should we. Changing the CurrentCulture of Thread.CurrentThread requires a SecurityPermission,
         * so if our application (for whatever reason) lacked this permission, it could crash.
         * Using a custom static field we're independent of permissions. */         
        public static CultureInfo CurrentCulture;
        internal static DataFile CurrentFile;
        internal static bool PlaySounds;
        internal static bool ShowDiscrepancies;

        public static Program program;

        [STAThread]
        static void Main()
        {
            try
            {
                CurrentTheme = new Theme();
                program = new Program();
            }
            catch (Exception x)
            {
                ReactTo(x);
            } 
        }
        
        public Program()
        {
            #region make sure there is no other instance of program running
            bool canIhasMutex;
            var mutex = new Mutex(
                true,
                Application.ProductName,
                out canIhasMutex);
            if (!canIhasMutex)
            {
                MessageBox.Show(
                    Resources.MESSAGEBOX_ERROR_AnotherApplicationInstanceRunning_MESSAGE,
                    Resources.MESSAGEBOX_ERROR_AnotherApplicationInstanceRunning_CAPTION,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                Environment.Exit(-1);
            }
            #endregion

            InitializeLog();
            
            CurrentCulture = new CultureInfo(Settings.Default.CULTURE);            
            MRURotasFiles = new MRUTracker(
                Settings.Default.REGISTRY_MRU_Rotas_Suffix,
                Settings.Default.MRU_Rotas_MaximumFiles);
            MRUSQLFiles = new MRUTracker(
                Settings.Default.REGISTRY_MRU_SQL_Suffix,
                Settings.Default.MRU_SQL_MaximumFiles);            
            
            PlaySounds = Settings.Default.SoundOnByDefault;
            ShowDiscrepancies = true;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            frmLogon = new Logon();            
            frmMain = new MainForm();
            frmEditNotes = new EditNotes();
            addempForm = new AddRowToTemplate();

            // for unhandled exceptions
            AppDomain.CurrentDomain.UnhandledException += (sender, e) => ReactTo((Exception)e.ExceptionObject);
            Application.ThreadException += (sender, e) => ReactTo(e.Exception);
            Application.Run(frmLogon);
            GC.KeepAlive(mutex); /* According to Jon Skeet: "we want the program to keep hold of the mutex
                                  * as long as it's running. But the JIT compiler sees that the mutex is only
                                  * used near the beginning of the program, and may discard it prematurely
                                  * when memory is needed for something else! This only happens with rather
                                  * large, complex programs and was a real puzzle to me.
                                  * GC.KeepAlive(x) means "I'm still using x at this point so it had better
                                  * not have been discarded."
                                  * 
                                  * My program isn't "large and complex", but still - good to know :) it costs nothing. */
        }

        public static void Quit()
        {
            MRURotasFiles.SaveList();
            MRUSQLFiles.SaveList();
            CloseLog();
            if (frmMain != null)
            {
                frmMain.DisableFormClosing();
                frmMain.Close();
            }
            Application.Exit();
        }

        

        

    }
}
